/*
 * Copyright 2022 The Open Islands Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.openislands.oi.apiserver.http;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.openislands.oi.apiserver.app.NodeService;
import org.openislands.oi.pojo.dto.NodeDTO;
import org.openislands.oi.pojo.dto.NodePageDTO;
import org.openislands.oi.pojo.dto.RouteDTO;
import org.openislands.oi.pojo.qo.NodeAddQO;
import org.openislands.oi.pojo.qo.NodePageQO;
import org.openislands.oi.pojo.qo.NodeResetQO;
import org.openislands.oi.pojo.qo.NodeUpdateQO;
import org.openislands.oi.pojo.vo.CommonResponse;
import org.openislands.oi.pojo.vo.NodeRouteVO;
import org.openislands.oi.pojo.vo.NodeVO;
import org.openislands.oi.util.ValueCopyUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.stream.Collectors;

@SuppressWarnings("unused")
@RestController
@RequestMapping("/v1/nodes")
public class NodeController {
    @Resource(type = NodeService.class)
    private NodeService nodeService;

    @PostMapping("/")
    public CommonResponse<Boolean> addNode(@Validated @RequestBody NodeAddQO addQO) {
        final NodeDTO nodeDTO = ValueCopyUtils.copyProperties(addQO, new NodeDTO(), (source, target) -> {
            target.setRouteDTOList(source.getNodeRouteList().stream()
                    .map((nodeRouteQO) -> ValueCopyUtils.copyProperties(nodeRouteQO, new RouteDTO()))
                    .collect(Collectors.toList())
            );
            return target;
        });
        Boolean bool = nodeService.addNode(nodeDTO);
        return CommonResponse.success(bool);
    }

    @DeleteMapping("/{nodeId}")
    public CommonResponse<Boolean> deleteNode(@PathVariable(value = "nodeId") String nodeId) {
        Boolean bool = nodeService.deleteNode(nodeId);
        return CommonResponse.success(bool);
    }

    @PutMapping("/")
    public CommonResponse<Boolean> updateNode(@Validated @RequestBody NodeUpdateQO updateQO) {
        final NodeDTO nodeDTO = ValueCopyUtils.copyProperties(updateQO, new NodeDTO());
        Boolean result = nodeService.updateNode(nodeDTO);
        return CommonResponse.success(result);
    }

    @PutMapping("/reset")
    public CommonResponse<Boolean> resetNode(@Validated @RequestBody NodeResetQO nodeResetQO) {
        final NodeDTO nodeDTO = ValueCopyUtils.copyProperties(nodeResetQO, new NodeDTO());
        Boolean result = nodeService.resetNode(nodeDTO);
        return CommonResponse.success(result);
    }

    @GetMapping("/{nodeId}")
    public CommonResponse<NodeVO> queryNode(@PathVariable(value = "nodeId") String nodeId) {
        NodeDTO nodeDTO = nodeService.queryByNodeId(nodeId);
        return CommonResponse.success(ValueCopyUtils.copyProperties(nodeDTO, new NodeVO(), (source, target) -> {
            target.setNodeRouteList(ValueCopyUtils.copyList(source.getRouteDTOList(), NodeRouteVO.class));
            return target;
        }));
    }

    @PostMapping("/page")
    public CommonResponse<Page<NodeVO>> queryPageNode(@Validated @RequestBody NodePageQO pageQO) {
        Page<NodeDTO> dtoPage = nodeService.queryPage(ValueCopyUtils.copyProperties(pageQO, new NodePageDTO()));
        return CommonResponse.success((Page<NodeVO>) dtoPage.convert(nodeDTO ->
                ValueCopyUtils.copyProperties(nodeDTO, new NodeVO(), (source, target) -> {
                    target.setNodeRouteList(source.getRouteDTOList().stream().map(routeDTO ->
                            ValueCopyUtils.copyProperties(routeDTO, new NodeRouteVO())).collect(Collectors.toList()));
                    return target;
                })
        ));
    }
}
